// Copyright (C) 1953-2023 NUDT
// Verilog module name - descriptor_output 
// Version: V4.3.0.20230322
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module descriptor_output
(
       i_clk,
       i_rst_n,
       
       i_storedfwd_fifo_empty,
       o_storedfwd_fifo_rd,
       iv_storedfwd_fifo_rdata,
       
       i_cutthroughfwd_fifo_empty,
       o_cutthroughfwd_fifo_rd,
       iv_cutthroughfwd_fifo_rdata,       
       
       ov_desp,
       o_desp_wr
);
// I/O
// clk & rst
input                  i_clk;
input                  i_rst_n;  
//fifo signal
input                  i_storedfwd_fifo_empty;
output reg             o_storedfwd_fifo_rd;
input          [87:0]  iv_storedfwd_fifo_rdata;

input                  i_cutthroughfwd_fifo_empty;
output reg             o_cutthroughfwd_fifo_rd;
input          [87:0]  iv_cutthroughfwd_fifo_rdata;
//descriptor output
output reg     [87:0]  ov_desp;
output reg             o_desp_wr;
//***************************************************
//               fifo read 
//***************************************************
reg         [1:0]   dou_state;
localparam  IDLE_S                            = 2'd0,
            OUTPUT_STOREDFWD_DESCRIPTOR_S     = 2'd1,
            OUTPUT_CUTTHROUGHFWD_DESCRIPTOR_S = 2'd2;   
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n) begin
        o_storedfwd_fifo_rd     <= 1'b0;  
        o_cutthroughfwd_fifo_rd <= 1'b0;         
        
        ov_desp <= 88'b0;
        o_desp_wr <= 1'b0;
        dou_state <= IDLE_S;
    end
    else begin
        case(dou_state)
            IDLE_S:begin
                ov_desp <= 88'b0;
                o_desp_wr <= 1'b0;
                if(!i_cutthroughfwd_fifo_empty)begin
                    o_cutthroughfwd_fifo_rd <= 1'b1;
                    dou_state <= OUTPUT_CUTTHROUGHFWD_DESCRIPTOR_S;                    
                end
                else if(!i_storedfwd_fifo_empty)begin
                    o_storedfwd_fifo_rd <= 1'b1;
                    dou_state <= OUTPUT_STOREDFWD_DESCRIPTOR_S;                    
                end
                else begin
                    o_storedfwd_fifo_rd     <= 1'b0;  
                    o_cutthroughfwd_fifo_rd <= 1'b0; 
                    dou_state <= IDLE_S;                         
                end
            end
            OUTPUT_CUTTHROUGHFWD_DESCRIPTOR_S:begin
                o_cutthroughfwd_fifo_rd <= 1'b0;
                ov_desp <= iv_cutthroughfwd_fifo_rdata;
                o_desp_wr <= 1'b1; 
                dou_state <= IDLE_S;                 
            end
            OUTPUT_STOREDFWD_DESCRIPTOR_S:begin
                o_storedfwd_fifo_rd <= 1'b0;
                ov_desp <= iv_storedfwd_fifo_rdata;
                o_desp_wr <= 1'b1; 
                dou_state <= IDLE_S;                 
            end            
            default:begin
                o_storedfwd_fifo_rd     <= 1'b0;  
                o_cutthroughfwd_fifo_rd <= 1'b0;         
                
                ov_desp <= 88'b0;
                o_desp_wr <= 1'b0;
                dou_state <= IDLE_S;
            end
        endcase
    end
end 
endmodule